#include "asynsocketclient.h"

#include "main_controller.h"

AsynSocketClient::AsynSocketClient(MainController *main_controller, boost::asio::io_service &io_service, tcp::endpoint &endpoint):
    io_service_(io_service), socket_(io_service), endpoint_(endpoint),main_controller_(main_controller)
{
}

void AsynSocketClient::Start()
{
    socket_.async_connect(endpoint_,
                          boost::bind(&AsynSocketClient::HandleConnect,
                                      shared_from_this(),
                                      boost::asio::placeholders::error));
}

void AsynSocketClient::AsyncWrite(const u_char *msg_data, const size_t len)
{
    if(len<=13)
    {
        cout<<"not enought frame length"<<endl;
        return;
    }
    boost::asio::async_write(socket_,boost::asio::buffer(msg_data,len),
                             boost::bind(&AsynSocketClient::HandleWrite,
                                         shared_from_this(),
                                         boost::asio::placeholders::error,
                                         boost::asio::placeholders::bytes_transferred));
}

void AsynSocketClient::Write(const u_char *msg_data, const size_t len)
{
    boost::asio::write(socket_,boost::asio::buffer(msg_data,len));
}

void AsynSocketClient::HandleDataCb(const u_char *msg_data, const size_t len)
{
    //cout<<"AsynSocketClient::HandleDataCb()"<<endl;
    main_controller_->RecvFrameData(msg_data,len);
}

void AsynSocketClient::HandleConnect(const boost::system::error_code &error)
{
    if (error)
    {
        if (error.value() != boost::system::errc::operation_canceled)
        {
            std::cerr << "socket connection error: "<<boost::system::system_error(error).what() << std::endl;
        }
        sleep(1);
        socket_.close();
        socket_.async_connect(endpoint_,
                              boost::bind(&AsynSocketClient::HandleConnect,
                                          shared_from_this(),
                                          boost::asio::placeholders::error));
        return;
    }

    static tcp::no_delay option(true);
    socket_.set_option(option);

    //boost::asio::write(socket_,boost::asio::buffer("client says hello"));

    socket_.async_read_some(boost::asio::buffer(frame_.recv_data),
                            boost::bind(&AsynSocketClient::HandleRead,
                                        shared_from_this(),
                                        boost::asio::placeholders::error,
                                        boost::asio::placeholders::bytes_transferred));
}

void AsynSocketClient::HandleWrite(const boost::system::error_code &error, size_t bytes_transferred)
{
    //memset(&recv_data, sizeof(recv_data), 0);
    if(error)
    {
        cout<<"error:"<<error.message()<<endl;
        return;
    }
    cout<<"write callback function"<<endl;
}

void AsynSocketClient::HandleRead(const boost::system::error_code &error, size_t bytes_transferred)
{
//    cout<<"async read callback function"<<endl;
    if(error)
    {
        cout<<"error:"<<error.message()<<endl;
        return;
    }
//    cout<<bytes_transferred<<": ";
//    for(size_t i = 0; i < bytes_transferred; i++)
//        cout <<(int)frame_.recv_data[i]<<" ";
//    cout << endl;

    frame_.ParseRecvData(bytes_transferred,shared_from_this());

    socket_.async_read_some(boost::asio::buffer(frame_.recv_data),
                             boost::bind(&AsynSocketClient::HandleRead,
                                         shared_from_this(),
                                         boost::asio::placeholders::error,
                                         boost::asio::placeholders::bytes_transferred));
}
